package com.yugao.fintech.draper.security.config;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.yugao.fintech.draper.security.handler.UrlAuthenticationEntryPoint;
import com.yugao.fintech.draper.security.support.CustomOpaqueTokenIntrospector;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
import org.springframework.security.web.SecurityFilterChain;

/**
 * 资源服务器配置
 */
@EnableWebSecurity
@RequiredArgsConstructor
public class ResourceServerConfigure {
    private final OAuth2AuthorizationService oAuth2AuthorizationService;
    private final BearerTokenResolver bearerTokenResolver;

    /**
     * 资源服务器属性配置
     */
    private final SecurityProperties properties;

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 放行配置文件中指定的请求
        String[] anonUrls = StringUtils.splitByWholeSeparatorPreserveAllTokens(properties.getAnonUris(),
                StringPool.COMMA);
        http.authorizeRequests(
                        authorizeRequests -> authorizeRequests
                                //.antMatchers(anonUrls)
								.requestMatchers(anonUrls)
                                .permitAll().anyRequest()
                                .authenticated())
                .oauth2ResourceServer(oauth2 -> oauth2
                        // 不透明令牌自省配置
                        .opaqueToken(token -> token.introspector(new CustomOpaqueTokenIntrospector(oAuth2AuthorizationService)))
                        .authenticationEntryPoint(new UrlAuthenticationEntryPoint())
                        .bearerTokenResolver(bearerTokenResolver))
                .headers()
                .frameOptions()
                .disable()
                .and()
                .csrf()
                .disable();
        return http.build();
    }

}
